/* eslint-disable no-param-reassign */
/* eslint-disable no-unused-expressions */
/* eslint-disable @typescript-eslint/explicit-function-return-type */
import {
  ref,
  PropType,
  computed,
  onMounted,
  onUnmounted,
  defineComponent,
} from 'vue';
import { IPanelRawItem } from '@ibiz/model-core';
import { debounce } from 'lodash-es';
import { useNamespace } from '@ibiz-template/vue3-util';
import { OdooChatController } from './odoo-chat.controller';
import { OdooChatWindow } from './chat-window/chat-window';
import './odoo-chat.scss';

/**
 * Odoo聊天
 */
export const OdooChat = defineComponent({
  name: 'IBizOdooChat',
  props: {
    modelData: {
      type: Object as PropType<IPanelRawItem>,
      required: true,
    },
    controller: {
      type: Object as PropType<OdooChatController>,
      required: true,
    },
  },
  setup(props) {
    const ns = useNamespace('odoo-chat');
    const c = props.controller;
    const optionsActive = ref<boolean>(false);
    const popoverVisible = ref<boolean>(false);

    const width = ref<number>(window.innerWidth);

    const chatWindows = computed(() => {
      const number = Math.floor((width.value - 60) / 400);
      // 超出的自动关闭
      c.state.chatList
        .filter(chat => chat.isOpen)
        .forEach((chat, index) => {
          if (index >= number) chat.isOpen = false;
        });
      return c.state.chatList.filter(chat => chat.isOpen);
    });

    /**
     * @description 处理最小化改变
     */
    const handleMinimizeChange = (): void => {
      c.state.isMinimize = !c.state.isMinimize;
    };

    /**
     * 处理大小改变
     */
    const handleResize = debounce(() => {
      width.value = window.innerWidth;
    }, 33.34);

    /**
     * @description 处理选项
     * @param {('minimize' | 'closeAll')} actionName
     */
    const handleOptions = (actionName: 'minimize' | 'closeAll') => {
      optionsActive.value = false;
      popoverVisible.value = false;
      actionName === 'minimize' ? handleMinimizeChange() : c.clearChat();
    };

    /**
     * @description 绘制聊天选项
     * @returns {*}
     */
    const renderChatOption = () => {
      return (
        <el-popover
          placement='top-end'
          trigger='click'
          onHide={() => {
            optionsActive.value = false;
          }}
          onShow={() => {
            optionsActive.value = true;
          }}
          v-model:visible={popoverVisible.value}
          popper-options={{
            modifiers: [
              {
                name: 'offset',
                options: {
                  offset: [0, 5],
                },
              },
            ],
          }}
        >
          {{
            reference: () => {
              return (
                <div
                  class={[
                    ns.e('options'),
                    ns.is('active', optionsActive.value),
                  ]}
                  title='聊天选项'
                >
                  <ion-icon name='ellipsis-horizontal'></ion-icon>
                </div>
              );
            },
            default: () => {
              return (
                <div class={ns.em('options', 'list')}>
                  <div
                    class={ns.em('options', 'item')}
                    onClick={() => handleOptions('minimize')}
                  >
                    <ion-icon name='eye-off-outline'></ion-icon>
                    隐藏所有对话
                  </div>
                  <div
                    class={ns.em('options', 'item')}
                    onClick={() => handleOptions('closeAll')}
                  >
                    <ion-icon name='close-outline'></ion-icon>
                    关闭所有对话
                  </div>
                </div>
              );
            },
          }}
        </el-popover>
      );
    };

    /**
     * @description 绘制最小化
     * @returns {*}
     */
    const renderMinimize = () => {
      return (
        <div
          title='显示所有聊天'
          class={[ns.e('bubble'), ns.em('bubble', 'minimize')]}
          onClick={handleMinimizeChange}
        >
          <ion-icon name='chatbubble-ellipses-outline'></ion-icon>
        </div>
      );
    };

    /**
     * @description 绘制聊天气泡
     * @returns {*}
     */
    const renderChatBubbles = () => {
      return (
        <div class={ns.e('bubbles')}>
          {c.state.isMinimize ? renderMinimize() : renderChatOption()}
          {!c.state.isMinimize &&
            c.state.chatList.map(chat => {
              if (!chat.isOpen)
                return (
                  <div
                    class={ns.e('bubble')}
                    title={chat.description}
                    onClick={() => c.onChartOpenChage(chat.key)}
                  >
                    <div
                      title='关闭聊天气泡'
                      class={ns.em('bubble', 'close-icon')}
                      onClick={(evt: MouseEvent) => {
                        evt.stopPropagation();
                        c.removeChat(chat.key);
                      }}
                    >
                      <ion-icon name='close-outline'></ion-icon>
                    </div>
                    {chat.icon ? (
                      <iBizIcon icon={chat.icon}></iBizIcon>
                    ) : (
                      <ion-icon name='chatbubbles-outline'></ion-icon>
                    )}
                  </div>
                );
              return null;
            })}
        </div>
      );
    };

    /**
     * @description 绘制聊天窗口
     * @returns {*}
     */
    const renderChatWindow = () => {
      if (!c.state.isMinimize)
        return (
          <div class={ns.e('windows')}>
            {chatWindows.value.map(chat => {
              return (
                <OdooChatWindow
                  item={chat}
                  key={chat.key}
                  class={ns.em('windows', 'item')}
                  onClose={() => c.onChartOpenChage(chat.key)}
                  onRemove={() => c.removeChat(chat.key)}
                />
              );
            })}
          </div>
        );
    };

    /**
     * @description 绘制内容
     * @returns {*}
     */
    const renderContent = () => {
      if (c.state.chatList.length)
        return [renderChatWindow(), renderChatBubbles()];
    };

    onMounted(() => {
      window.addEventListener('resize', handleResize);
    });

    onUnmounted(() => {
      window.removeEventListener('resize', handleResize);
      c.destroy();
    });

    return { ns, renderContent };
  },
  render() {
    return <div class={this.ns.b()}>{this.renderContent()}</div>;
  },
});
